#include "syscall.h"
#include "isr.h"
#include "print.h"
#include "video.h"

DEFN_SYSCALL1(printf, 0, const char*);
DEFN_SYSCALL1(print_hex, 1, int);
DEFN_SYSCALL1(print_dec, 2, int);
DEFN_SYSCALL0(getch, 3);
DEFN_SYSCALL1(panic, 4, const char*);
DEFN_SYSCALL1(print_ch, 5, char);
DEFN_SYSCALL1(inportb, 6, unsigned short);
DEFN_SYSCALL2(outportb, 7, unsigned short, unsigned char);

static void syscall_handler(regs *r);

static void *syscalls[8] = 
{
	&printf,
	&print_hex,
	&print_dec,
	&getch,
	&panic,
	&print_ch,
	&inportb,
	&outportb
};

unsigned int num_syscalls = 8;

void initialize_syscalls()
{
	register_interrupt_handler(48, &syscall_handler);
}

void syscall_handler(regs *r)
{
	if(r->eax >= num_syscalls)
		return;
	
	void *loc = syscalls[r->eax];
	
	int ret;
	asm volatile (" \
		push %1; \
		push %2; \
		push %3; \
		push %4; \
		push %5; \
		call *%6; \
		pop %%ebx; \
		pop %%ebx; \
		pop %%ebx; \
		pop %%ebx; \
		pop %%ebx; \
		" : "=a" (ret) : "r" (r->edi), "r" (r->esi), "r" (r->edx), "r" (r->ecx), "r" (r->ebx), "r" (loc));
	r->eax = ret;
} 
